<?php
namespace Hilaoyu\ComputeCloudClient\Api;

use AlibabaCloud\SDK\Cbn\V20170912\Models\AttachCenChildInstanceRequest;
use AlibabaCloud\SDK\Cbn\V20170912\Models\CreateCenRequest;
use AlibabaCloud\SDK\Cbn\V20170912\Models\DeleteCenRequest;
use AlibabaCloud\SDK\Cbn\V20170912\Models\DescribeCenAttachedChildInstancesRequest;
use AlibabaCloud\SDK\Cbn\V20170912\Models\DescribeCensRequest;
use AlibabaCloud\SDK\Cbn\V20170912\Models\DetachCenChildInstanceRequest;
use Hilaoyu\ComputeCloudClient\AssetModel;
use Hilaoyu\ComputeCloudClient\AssetModels;
use Hilaoyu\ComputeCloudClient\Interfaces\ApiCbnInterface;
use Hilaoyu\Utils\UtilArr;
use Hilaoyu\Utils\UtilStr;

/**
 * Class AliCbn
 * @package Hilaoyu\ComputeCloudClient\Api
 * @property  \AlibabaCloud\SDK\Cbn\V20170912\Cbn $client
 */
class AliCbn extends AliApiBase implements ApiCbnInterface
{

    public function cenCreate(string $name,string $description=''):?AssetModel{
        $name = trim($name);
        try{
            $request = new CreateCenRequest([
                'name'        => $name,
                'description'            => $description,
            ]);
            $result = $this->client->createCen($request);

            $datum = $result->body->toMap();
            $id = UtilArr::get($datum,'CenId');
            if(!$id){
                throw new \Exception('返回数据错误');
            }

            $model = new AssetModel();
            $model->type ='cen';
            $model->asset_id = $id;
            $model->name = $name;
            $model->status = 'Pending';
            return $model;
        }catch (\Exception $exception){
            $this->setError($exception->getMessage());
        }
        return null;

    }

    public function censDescribe(array $names=[],array $cenIds=[]):AssetModels{
        $models = new AssetModels();
        try{
            $params = ['pageSize' => 50];
            $filters = [];
            if(!empty($names)){
                if(count($names) > 5){
                    $names = array_splice($names,0,5);
                }
                $filters[] = new DescribeCensRequest\filter([
                    "key" => "Name",
                    "value" => $names
                ]);
            }
            if(!empty($cenIds)){
                if(count($cenIds) > 5){
                    $cenIds = array_splice($cenIds,0,5);
                }
                $filters[] = new DescribeCensRequest\filter([
                    "key" => "CenId",
                    "value" => $cenIds
                ]);
            }

            if(!empty($filters)){
                $params['filter'] = $filters;
            }

            $request = new DescribeCensRequest($params);
            $result = $this->client->describeCens($request);

            $data = (array)UtilArr::get($result->body->toMap(), 'Cens.Cen');
            foreach ($data as $datum){
                $id = UtilArr::get($datum,'CenId');
                if(!$id){
                    continue;
                }

                $model = new AssetModel();
                $model->type ='cen';
                $model->asset_id = $id;
                $model->name = UtilArr::get($datum,'Name');
                $model->status = UtilArr::get($datum,'Status');
                $models->push($model);
            }

        }catch (\Exception $exception){
            $this->setError($exception->getMessage());
        }
        return $models;
    }

    public function cenDescribe(string $cenId):?AssetModel
    {
        $cenId = trim($cenId);
        $models = $this->censDescribe([],[$cenId]);
        if(!$models){
            return null;
        }

        return $models->first(function ($item) use ($cenId){
            return $item->asset_id == $cenId;
        });

    }

    public function cenDelete(string $cenId):bool{
        $cenId = trim($cenId);
        if(!$cenId){
            return false;
        }
        if(!$this->cenDescribe($cenId)){
            return true;
        }

        try{
            $request = new DeleteCenRequest([
                'cenId'        => $cenId,
            ]);
            $result = $this->client->deleteCen($request);

            return (bool)$result->body->toMap();
        }catch (\Exception $exception){
            $this->setError($exception->getMessage());
        }
        return false;
    }


    public function cenChildInstanceAttach(string $cenId,string $childInstanceId,string $childInstanceType='VPC',string $childInstanceRegionId='',int $childInstanceOwnerId = 0):bool{
        $cenId = trim($cenId);
        $childInstanceRegionId = $this->getRegionId($childInstanceRegionId);
        if(!$cenId){
            return false;
        }

        try{
            $params = [
                "cenId" => $cenId,
                "childInstanceId" => trim($childInstanceId),
                "childInstanceType" => trim($childInstanceType),
                "childInstanceRegionId" => trim($childInstanceRegionId),
            ];
            if($childInstanceOwnerId > 0){
                $params['childInstanceOwnerId'] = $childInstanceOwnerId;
            }
            $request = new AttachCenChildInstanceRequest($params);
            $result = $this->client->attachCenChildInstance($request);

            return (bool)$result->body->toMap();
        }catch (\Exception $exception){
            $this->setError($exception->getMessage());
        }

        return false;
    }

    public function cenAttachedChildInstancesDescribe(string $cenId,string $childInstanceType='',string $childInstanceRegionId=''):AssetModels{
        $models = new AssetModels();
        $cenId = trim($cenId);
        if(!$cenId){
            return $models;
        }
        try{
            $request = new DescribeCenAttachedChildInstancesRequest([
                'pageSize' => 50,
                "cenId" => $cenId,
                "childInstanceType" => trim($childInstanceType),
                "childInstanceRegionId" => trim($childInstanceRegionId),
            ]);
            $result = $this->client->describeCenAttachedChildInstances($request);

            $data = (array)UtilArr::get($result->body->toMap(), 'ChildInstances.ChildInstance');
            foreach ($data as $datum){
                $id = UtilArr::get($datum,'ChildInstanceId');
                if(!$id){
                    continue;
                }

                $model = new AssetModel();
                $model->type = UtilStr::lower(UtilArr::get($datum,'ChildInstanceType'));
                $model->asset_id = $id;
                $model->name = $id;
                $model->region_id = UtilArr::get($datum,'ChildInstanceRegionId');
                $model->owner_id = UtilArr::get($datum,'ChildInstanceOwnerId');
                $model->status = UtilArr::get($datum,'Status');
                $models->push($model);
            }

        }catch (\Exception $exception){
            $this->setError($exception->getMessage());
        }
        return $models;

    }

    public function cenChildInstanceDetach(string $cenId,string $childInstanceId,string $childInstanceType='VPC',string $childInstanceRegionId='',int $childInstanceOwnerId = 0):bool{
        $cenId = trim($cenId);
        $childInstanceRegionId = $this->getRegionId($childInstanceRegionId);
        if(!$cenId){
            return false;
        }

        try{
            $params = [
                "cenId" => $cenId,
                "childInstanceId" => trim($childInstanceId),
                "childInstanceType" => trim($childInstanceType),
                "childInstanceRegionId" => trim($childInstanceRegionId),
            ];
            if($childInstanceOwnerId > 0){
                $params['childInstanceOwnerId'] = $childInstanceOwnerId;
            }
            $request = new DetachCenChildInstanceRequest($params);
            $result = $this->client->detachCenChildInstance($request);

            return (bool)$result->body->toMap();
        }catch (\Exception $exception){
            $this->setError($exception->getMessage());
        }

        return false;
    }


}
